// pages/recorder/index.js
const recorderManager = wx.getRecorderManager()
let innerAudioContext
Page({

  /**
   * 页面的初始数据
   */
  data: {
    popupShow: false,
    recordState: false,
    audioPath: '',
    isPlaying: false //是否正在播放
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    
    this.initRecorder()
    this.initInnerAudio()
    
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
    this.destroyInnerAudio()
  },

  /** 初始化录音器 */
  initRecorder(){
    recorderManager.onStart(() => {
      console.log('recorder start')
    })
    recorderManager.onPause(() => {
      console.log('recorder pause')
    })
    recorderManager.onStop((res) => {
      console.log('recorder stop', res)
      const { tempFilePath } = res
      this.setData({
        audioPath: tempFilePath
      })

      innerAudioContext.src = tempFilePath /**你要播放的音频文件的地址 可以放在线的也可以放本地的，本地的需要用绝对地址 */
    })
    recorderManager.onFrameRecorded((res) => {
      const { frameBuffer } = res
      console.log('frameBuffer.byteLength', frameBuffer.byteLength)
    })
    recorderManager.onError((res) => {
      console.log('recorder error', res)
      if (res.errMsg === "operateRecorder:fail NotFoundError") {
        this.setData({
          recordState: false,
        })
        wx.showToast({
          title: '您的麦克风暂无法使用',
          icon: 'none',
          mask: true
        })
      }
    })
  },
  
  /** 初始化播放音频 */
  initInnerAudio(){
    // 播放音频文件
    innerAudioContext = wx.createInnerAudioContext() /**微信小程序开发文档自带的音频方法 */
    // innerAudioContext.src = 'https://ln-sycdn.kuwo.cn/4acedfddf119f10ffce34cf99f6d61d6/660382a3/resource/n2/85/50/2424230609.mp3' /**你要播放的音频文件的地址 可以放在线的也可以放本地的，本地的需要用绝对地址 */
    // decodeURIComponent()解码由 encodeURIComponent 方法或者其他类似方法编码的部分统一资源标识符（URI）
    
    this.audioPlay = innerAudioContext.onPlay(() => {
      /**开始播放是触发 */
      console.log('Start playback')
      this.setData({
        isPlaying: true
      })
    })
    
    this.audioPause = innerAudioContext.onPause(() => {
      /**开始播放是触发 */
      console.log('Pause playback')
      this.setData({
        isPlaying: false
      })
    })
    
    this.audioEnded = innerAudioContext.onEnded(() => {
      /**监听音频自然播放至结束的事件 */
      console.log('ended playback')
      this.setData({
        isPlaying: false
      })
    })

    this.audioStop = innerAudioContext.onStop(() => {
      /**监听音频停止事件 */
      console.log('stop playback')
      this.setData({
        isPlaying: false
      })
    })
    
    this.audioError = innerAudioContext.onError((res) => {
      /**播放是有错误时触发 */
      console.log(res.errMsg)
      console.log(res.errCode)
      let toastTitle = ''
      switch (res.errCode) {
        case 10001:
          toastTitle = '系统错误'
          break;
        case 10002:
          toastTitle = '网络错误'
          break;
        case 10003:
          toastTitle = '文件错误'
          break;
        case 10004:
          toastTitle = '格式错误'
          break;
        case -1:
          toastTitle = '未知错误'
          break;
        default:
          break;
      }

      toastTitle !== '' && wx.showToast({
        title: toastTitle,
        icon: 'none',
        mask: true
      })
      this.setData({
        isPlaying: false
      })
    })
  },

  /** 销毁播放音频 */
  destroyInnerAudio(){
    innerAudioContext.offPlay(this.audioPlay) // 移除音频播放事件的监听函数
    innerAudioContext.offPause(this.audioPause) // 移除音频暂停事件的监听函数
    innerAudioContext.offEnded(this.audioEnded) // 移除音频自然播放至结束的事件的监听函数
    innerAudioContext.offStop(this.audioStop) // 移除音频停止事件的监听函数
    innerAudioContext.offError(this.audioError) // 移除音频播放错误事件的监听函数
    innerAudioContext.destroy() //销毁当前实例
  },

  showPopup(){
    this.setData({
      popupShow: true
    })
  },

  // 弹窗关闭
  onClosePopup() {
    this.setData({ 
      popupShow: false,
    })
  },

   // 录音开始
   touchStart(){
    console.log('start');
    // 防止 -30011
    if (this.data.recordState) return
    const options = {
      duration: 60000, //录音的时长，单位 ms，最大值 600000（10 分钟）
      sampleRate: 44100, //采样率（pc不支持）
      numberOfChannels: 1, //录音通道数
      encodeBitRate: 192000, //编码码率
      format: 'mp3', //音频格式
      frameSize: 50 //指定帧大小，单位 KB。传入 frameSize 后，每录制指定帧大小的内容后，会回调录制的文件内容，不指定则不会回调。暂仅支持 mp3、pcm 格式。
    }
    recorderManager.start(options)
    this.setData({
      recordState: true  //录音状态
    })
  },

  // 录音结束
  touchEnd(){
    console.log('end');
    recorderManager.stop()
    // 防止重复触发stop函数 -30012
    if(!this.data.recordState) {
      console.warn("has finished!")
      return
    }
    this.setData({
      recordState: false,
      popupShow: false
    })
  },

  // 权限询问
  getRecordAuth() {
    const _this = this
    wx.getSetting({
      success: (res) => {
        console.log("succ")
        console.log(res)
        if (!res.authSetting['scope.record']) {
          wx.authorize({
            scope: 'scope.record',
            success() {
                // 用户已经同意小程序使用录音功能，后续调用 wx.startRecord 接口不会弹窗询问
                console.log("succ auth")
                _this.setData({ popupShow: true });
            }, fail: () => {
                console.log("fail auth")
                // this.touchStart()
                // return
                this.userAuthFail('scope.record', '请授权录音服务，用于获取语音识别').then(authRecordRes => {
                  console.log(authRecordRes);
                  _this.setData({ 
                    popupShow: authRecordRes,
                   });
                }).catch(authRecordErr => {
                  console.log(authRecordErr);
                  wx.showToast({
                    title: authRecordErr,
                    icon: 'none',
                    duration: 2000,
                  })
                })
            }
          })
        } else {
          console.log("record has been authed")
          _this.setData({ popupShow: true });
        }
      }, fail(res) {
        console.log("fail")
        console.log(res)
      }
    })
  },

  /**
  * 用户拒绝授权
  * @param {string} scope 需授权的权限
  * @param {string} tip 权限对应的提示
  */
  userAuthFail(scope, tip) {
    return new Promise((resolve, reject) => {
      wx.showModal({
        title: '提示',
        content: tip,
        confirmText: '去授权',
        cancelText: '不授权',
        success(res) {
        if (res.confirm) {
          wx.openSetting({
            success: (res) => {
              resolve(res.authSetting[scope])
            }
          })
        }
        if (res.cancel) {
          reject('您拒绝了授权')
        }
        },
      })
    })  
  },


  /** 播放语音 */
  playAudio(){
    console.log('播放');
    innerAudioContext.play()
  },

  /**暂停播放 */
  pausePlayAudio(){
    console.log('暂停');
    /**暂停后的音频再播放会从暂停处开始播放 */
    innerAudioContext.pause()
  }
})